import axios, { AxiosRequestConfig, AxiosResponse, AxiosError, AxiosInstance } from 'axios'
import { getToken, removeToken } from '@/utils/auth'
import { ACCESS_TOKEN_KEY } from '@/utils/vars'
import { Notify } from 'vant'

const createSever = (baseURL: string, timeout = 5 * 1000, withCredentials = true) => {
  const service: AxiosInstance = axios.create({ baseURL, withCredentials, timeout })

  service.interceptors.request.use((config: AxiosRequestConfig) => {
    config.headers[ACCESS_TOKEN_KEY] = getToken()
    return config
  }, e => Promise.reject(e))

  service.interceptors.response.use(async ({ headers, data }: AxiosResponse) => {
    const contentType = headers['content-type']
    // 如果不是json则直接返回data
    if (contentType && !/json/.test(contentType)) {
      return data
    }
    const res = data || {}
    if (res instanceof Blob && /json/.test(res.type)) {
      return JSON.parse(await res.text())
    }
    if (+res.code === 0 || +res.code === 200) {
      return res
    } else {
      const msg = res.message || '接口没有返回任何消息，请联系管理员！'
      Notify({ type: 'danger', message: msg })
      return Promise.reject(new Error(msg))
    }
  }, (error: AxiosError) => {
    const { status, config = {} } = error.response || { status: 0 }
    switch (status) {
      case 400:
        error.message = '请求错误(400)'
        break
      case 401:
        error.message = '未授权,请登录(401)'
        break
      case 403:
        error.message = '拒绝访问(403)'
        break
      case 404:
        error.message = `请求地址出错: ${config.url}`
        break
      case 405:
        error.message = '请求方法未允许(405)'
        break
      case 408:
        error.message = '请求超时(408)'
        break
      case 500:
        error.message = '服务器内部错误(500)'
        break
      case 501:
        error.message = '服务未实现(501)'
        break
      case 502:
        error.message = '网络错误(502)'
        break
      case 503:
        error.message = '服务不可用(503)'
        break
      case 504:
        error.message = '网络超时(504)'
        break
      case 505:
        error.message = 'HTTP版本不受支持(505)'
        break
      default:
        error.message = `连接错误: ${error.message}`
    }
    Notify({ type: 'danger', duration: 3000, message: error.message })
    if (status === 401) {
      removeToken()
      location.reload()
    }
    return Promise.reject(error)
  }
  )
  return service
}

const service: AxiosInstance = createSever(process.env.VUE_APP_BASE_API)

export default (config: AxiosRequestConfig) => {
  return service(config)
}
